package com.msgc.utils.crypto.asymmetric.store.impl;

import com.msgc.utils.JsonUtil;
import com.msgc.utils.crypto.asymmetric.dto.KeyPairDto;
import com.msgc.utils.crypto.asymmetric.exception.KeyPairException;
import com.msgc.utils.crypto.asymmetric.exception.NoSuchKeyPairException;
import com.msgc.utils.crypto.asymmetric.factory.AsymmetricKeyPairFactory;
import com.msgc.utils.crypto.asymmetric.store.KeyPairCache;
import com.msgc.utils.crypto.common.ByteSpecification;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;

import javax.annotation.PostConstruct;
import java.security.KeyPair;

/**
 * RSA 秘钥存储-Redis 存储，适合集群部署场景
 * @author liuyanming 2019年12月18日
 */

public class RedisKeyPairCache implements KeyPairCache {

	private RedisTemplate<String, Object> redisTemplate;

	private AsymmetricKeyPairFactory keyPairFactory;
	
    private String keyPrefix;

	public RedisKeyPairCache(RedisTemplate<String, Object> redisTemplate, AsymmetricKeyPairFactory keyPairFactory, String keyPrefix) {
		this.keyPrefix = keyPrefix;
		this.redisTemplate = redisTemplate;
		this.keyPairFactory = keyPairFactory;
	}

	@Override
	public void set(String id, KeyPair keyPair) {
		String key = addRedisPrefix(id);
		KeyPairDto dto = new KeyPairDto(keyPair);
		redisTemplate.opsForValue().setIfAbsent(key, JsonUtil.toJson(dto));
	}
	
	@Override
	public KeyPair get(String id) throws NoSuchKeyPairException {
		String key = addRedisPrefix(id);
		Object kp = redisTemplate.opsForValue().get(key);
		if (kp != null) {
			KeyPairDto dto = JsonUtil.toObject(String.valueOf(kp), KeyPairDto.class);
			try {
				return keyPairFactory.buildFrom(
						ByteSpecification.decodeToBytes(dto.getPk()),
						ByteSpecification.decodeToBytes(dto.getVk())
				);
			} catch (KeyPairException e) {
				throw new RuntimeException(e);
			}
		} else {
			throw new NoSuchKeyPairException("can't found keyPair id= " + id);
		}
	}
	
	private String addRedisPrefix(String id) {
		return keyPrefix + id;
	}


	@PostConstruct
	public void init() {
		LoggerFactory.getLogger(RedisKeyPairCache.class).debug("KeyPairCache-redis init.");
	}


	@Override
	public void destroy() {
		
	}
	
}
